package com.yingsheng.bi.hks.template.controller.processor;

import com.yingsheng.bi.hks.template.events.Event;
import com.yingsheng.bi.hks.template.events.HandlerMethodEvent;
import com.yingsheng.bi.hks.template.processor.InnerProcessor;
import org.apache.commons.io.IOUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

public class HttpInputMessageProcessor extends InnerProcessor {

    @Override
    public void execInner(Event event) {
        if (event instanceof HandlerMethodEvent) {
            HandlerMethodEvent handlerMethodEvent = (HandlerMethodEvent) event;
            Object sourceInput = handlerMethodEvent.getInput();
            if (sourceInput instanceof HttpInputMessage) {
                HttpInputMessage inputMessage = (HttpInputMessage) sourceInput;
                byte[] bodyByteArray = getBody(inputMessage);
                Charset charset = handlerMethodEvent.getCharset();
                String bodyString = new String(bodyByteArray, charset);
                handlerMethodEvent.setInput(bodyString);
                super.execInner(event);
                Object output = handlerMethodEvent.getOutput();
                handlerMethodEvent.setOutput(new HttpInputMessage() {

                    @Override
                    public HttpHeaders getHeaders() {
                        return inputMessage.getHeaders();
                    }

                    @Override
                    public InputStream getBody() {
                        if (output != null) {
                            byte[] bodyByteArray = output.toString().getBytes(charset);
                            return new ByteArrayInputStream(bodyByteArray);
                        } else {
                            byte[] bodyByteArray = bodyString.getBytes(charset);
                            return new ByteArrayInputStream(bodyByteArray);
                        }
                    }
                });
            } else {
                super.execInner(event);
            }
        } else {
            super.execInner(event);
        }
    }

    private byte[] getBody(HttpInputMessage inputMessage) {
        try {
            byte[] bodyByteArray = IOUtils.toByteArray(inputMessage.getBody());
            return bodyByteArray;
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

}
